﻿using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using ZilLion.Service.Core.ConfigManager.Manager;
using ZilLion.Service.Core.Ioc;
using ZilLion.Service.Core.WebSocket.Interface;
using ZilLion.Service.Core.WebSocket.MessagePersistence;

namespace ZilLion.Service.Core.WebSocket
{
    public static class WebSocketManagerExtensions
    {
        public static IServiceCollection AddWebSocketManager(this IServiceCollection services)
        {
            //注册瞬时,(但是handle 为单例,所以每个handler 的ConnectionManager 是单例的,对应到handle 使用的方式,也就是一个PATH 对应的ConnectionManager 是一个)
            services.TryAddTransient<WebSocketConnectionManager>();

            var config = ZilLionConfigurationManager.GetConfigInstance<WebSocketServiceConfig>();
            if (config == null) return services;
            switch (config.WebSocketPersistenceType)
            {
                case WebSocketPersistenceType.Local:
                    services.TryAddTransient<IMessagePersistenceHandle, LocalMessagePersistenceHandle>();
                    break;
                case WebSocketPersistenceType.Redis:
                    services.TryAddTransient<IMessagePersistenceHandle, RedisMessagePersistenceHandle>();
                    break;
                case WebSocketPersistenceType.Sqlserver:
                    services.TryAddTransient<IMessagePersistenceHandle, DbMessagePersistenceHandle>();
                    break;
                default:
                    services.TryAddTransient<IMessagePersistenceHandle, LocalMessagePersistenceHandle>();
                    break;
            }
            return services;
        }

        public static IApplicationBuilder MapWebSocketManager(this IApplicationBuilder applicationBuilder)
        {
            foreach (var icomponentLoader in IocConfig.ComponentLoaderCache.Values)
            foreach (var socketHandlType in icomponentLoader.WebSocketHandlTypes.ToArray())
                applicationBuilder.Map(
                    $"/websocket/{socketHandlType.Name.ToLower().Replace("websockethandler", string.Empty)}",
                    app => app.UseMiddleware<WebSocketManagerMiddleware>(IocContainer.Resolve(socketHandlType)));
            return applicationBuilder;
        }
    }
}